home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / exampleCode / games / seahaven / card.c++ < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  7.8 KB  |  320 lines

  1. /*
  2.  * Copyright 1992, 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /*
  18.  * Author:  Terry Weissman
  19.  *          weissman@sgi.com
  20.  */
  21.  
  22. #include "seahaven.h"
  23.  
  24. extern char *card_bits[52];
  25.  
  26. struct WindowCardRec {
  27.     Window window;
  28.     Card card;
  29. };
  30.  
  31. typedef struct WindowCardRec *WindowCard;
  32.  
  33. static WindowCardRec windowcard[100];
  34. static int numwindowcard = 0;
  35.  
  36. static GC highlightgc;
  37.  
  38. static void RegisterWindow(Card card, Window window) {
  39.     int i;
  40.     if (windowcard == 0 || window > windowcard[numwindowcard - 1].window) {
  41.     windowcard[numwindowcard].window = window;
  42.     windowcard[numwindowcard].card = card;
  43.     numwindowcard++;
  44.     return;
  45.     }
  46.     for (i=0 ; i<numwindowcard ; i++) {
  47.     if (windowcard[i].window > window) {
  48.         for (int j = numwindowcard ; j > i ; j--) {
  49.         windowcard[j] = windowcard[j-1];
  50.         }
  51.         windowcard[i].window = window;
  52.         windowcard[i].card = card;
  53.         numwindowcard++;
  54.         return;
  55.     }
  56.     }
  57.     Punt("Bug in RegisterWindow!");
  58. }
  59.  
  60.  
  61. Card WindowToCard(Window w) {
  62.     int l, h, i;
  63.     l = 0;
  64.     h = numwindowcard;
  65.     while (l < h) {
  66.     i = (l + h) / 2;
  67.     if (w == windowcard[i].window) return windowcard[i].card;
  68.     if (w > windowcard[i].window) l = i + 1;
  69.     else h = i;
  70.     }
  71.     if (w == windowcard[i].window) return windowcard[i].card;
  72.     return NULL;
  73. }
  74.  
  75.  
  76.  
  77. CardRec::CardRec(int s, int v, unsigned long fore, unsigned long back,
  78.          char *bitmap) {
  79.     suit = s;
  80.     value = v;
  81.     XSetWindowAttributes attributes;
  82.     long valuemask = CWEventMask | CWBackPixmap;
  83.     attributes.event_mask =
  84.     ButtonPressMask | ButtonReleaseMask | ButtonMotionMask;
  85.     attributes.background_pixmap =
  86.     XCreatePixmapFromBitmapData(dpy, toplevel, bitmap,
  87.                     CARDWIDTH, CARDHEIGHT, fore, back,
  88.                     DefaultDepth(dpy, screen));
  89.     window = XCreateWindow(dpy, toplevel, v * CARDWIDTH, s * CARDHEIGHT,
  90.                CARDWIDTH, CARDHEIGHT, 0, (int) CopyFromParent,
  91.                InputOutput, (Visual *) CopyFromParent,
  92.                valuemask, &attributes);
  93.     XMapWindow(dpy, window);
  94.     RegisterWindow(this, window);
  95. }
  96.  
  97.  
  98. Stack CardRec::getStack() {
  99.     return stack;
  100. }
  101.  
  102. // single stacks are symmetric for saving purposes
  103. Stack CardRec::getFoldedStack() {
  104.     if (stack ==singlestack[0] || stack == singlestack[1]
  105.             || stack == singlestack[2] || stack == singlestack[3])
  106.       return singlestack[0];
  107.     else
  108.       return stack;
  109. }
  110.  
  111. int CardRec::getSuit() {
  112.     return suit;
  113. }
  114.  
  115. int CardRec::getValue() {
  116.     return value;
  117. }
  118.  
  119. int CardRec::getX() {
  120.     return x;
  121. }
  122.  
  123. int CardRec::getY() {
  124.     return y;
  125. }
  126.  
  127. // single stacks are symmetric for saving purposes
  128. int CardRec::getFoldedY() {
  129.     if (stack ==singlestack[0] || stack == singlestack[1]
  130.             || stack == singlestack[2] || stack == singlestack[3])
  131.       return 0;
  132.     else
  133.       return y;
  134. }
  135.  
  136. void CardRec::setLoc(int newx, int newy) {
  137.     if (x != newx || y != newy) {
  138.     x = newx;
  139.     y = newy;
  140.     XMoveWindow(dpy, window, x, y);
  141.     }
  142. }
  143.  
  144.  
  145. void CardRec::raise() {
  146.     XRaiseWindow(dpy, window);
  147. }
  148.  
  149.  
  150. void CardRec::raiseAbove(Card c) {
  151.     XWindowChanges values;
  152.     values.sibling = c->window;
  153.     values.stack_mode = Above;
  154.     XConfigureWindow(dpy, window, CWSibling | CWStackMode, &values);
  155. }
  156.  
  157.  
  158. void CardRec::raiseBelow(Card c) {
  159.     XWindowChanges values;
  160.     values.sibling = c->window;
  161.     values.stack_mode = Below;
  162.     XConfigureWindow(dpy, window, CWSibling | CWStackMode, &values);
  163. }
  164.  
  165. void CardRec::setStack(Stack s) {
  166.     stack = s;
  167. }
  168.  
  169.  
  170. void CardRec::highlight() {
  171.     XFillRectangle(dpy, window, highlightgc, 0, 0, CARDWIDTH, CARDHEIGHT);
  172. }
  173.  
  174. void CardRec::repaint() {
  175.     XClearWindow(dpy, window);
  176. }
  177.  
  178.  
  179.  
  180. Bool CardHandleEvent(XEvent *event) {
  181.     Card card = WindowToCard(event->xany.window);
  182.     if (!card || event->type == KeyPress) return False;
  183.     if (event->type == ButtonPress) {
  184.     if (event->xbutton.button > 1) {
  185.         int suit = card->getSuit();
  186.         int value =
  187.         card->getValue() + ((event->xbutton.button == 3) ? 1 : -1);
  188.         if (value < 0 || value >= NUMVALUES) return True;
  189.         cards[suit][value]->highlight();
  190.         XEvent ev;
  191.         do {
  192.         GetInterestingEvent(&ev);
  193.         } while (ev.type != ButtonRelease);
  194.         cards[suit][value]->repaint();
  195.         return True;
  196.     }
  197.     Card list[20];
  198.     int origx[20], origy[20];
  199.     int num = 0;
  200.     int i;
  201.     for (; card ; card = card->getStack()->getCardAbove(card)) {
  202.         origx[num] = card->getX();
  203.         origy[num] = card->getY();
  204.         list[num++] = card;
  205.     }
  206.     list[num-1]->raise();
  207.     for (i=num-2 ; i>=0 ; i--) {
  208.         list[i]->raiseBelow(list[i+1]);
  209.     }
  210.     Bool abort = False;
  211.     for (;;) {
  212.         XEvent ev;
  213.         GetInterestingEvent(&ev);
  214.         if (ev.type == ButtonPress) {
  215.         abort = True;
  216.         break;
  217.         }
  218.         while (ev.type == MotionNotify && XPending(dpy)) {
  219.         XEvent ev2;
  220.         XPeekEvent(dpy, &ev2);
  221.         if (ev2.type == Expose) {
  222.             XNextEvent(dpy, &ev2);
  223.             if (ev2.xexpose.count == 0) score->repaint();
  224.             continue;
  225.         }
  226.         if (ev2.type != MotionNotify) break;
  227.         GetInterestingEvent(&ev);
  228.         }
  229.         if (ev.type == MotionNotify || ev.type == ButtonRelease) {
  230.         for (i=0 ; i<num ; i++) {
  231.             list[i]->setLoc
  232.             (origx[i] + ev.xbutton.x_root - event->xbutton.x_root,
  233.              origy[i] + ev.xbutton.y_root - event->xbutton.y_root);
  234.         }
  235.         if (ev.type == ButtonRelease) {
  236.             Stack stack =
  237.             StackFromPoint(list[0]->getX(), list[0]->getY());
  238.             if (!stack || stack == list[0]->getStack()) {
  239.             abort = True;
  240.             }
  241.             if (!abort && stack->getType() == Single) {
  242.             if (NumAvailableSingles() < num) abort = True;
  243.             if (!abort && !stack->addCard(list[num-1])) {
  244.                 abort = True;
  245.             }
  246.             if (!abort) {
  247.                 for (i=num-2 ; i>=0 ; i--) {
  248.                 GetAvailableSingle()->addCard(list[i]);
  249.                 }
  250.                 AutoMoves();
  251.                 UndoBoundary();
  252.                 break;
  253.             }
  254.             }
  255.             for (i=1 ; i<num ; i++) {
  256.             if (list[i]->getSuit() != list[i-1]->getSuit() ||
  257.                list[i]->getValue() != list[i-1]->getValue() - 1) {
  258.                 abort = True;
  259.                 break;
  260.             }
  261.             }
  262.             if (NumAvailableSingles() < num - 1) abort = True;
  263.             if (!abort && num > 1) {
  264.             Card top = stack->getTopCard();
  265.             if ((top == NULL &&
  266.                  list[0]->getValue() != NUMVALUES - 1)
  267.                 || (top != NULL &&
  268.                 (top->getSuit() != list[0]->getSuit() ||
  269.                  top->getValue() !=
  270.                      list[0]->getValue() + 1))) {
  271.                 abort = True;
  272.             } else {
  273.                 for (i=num-1 ; i>0 ; i--) {
  274.                 GetAvailableSingle()->addCard(list[i],
  275.                                   DontMove);
  276.                 }
  277.             }
  278.             }
  279.             if (!abort && !stack->addCard(list[0])) abort = True;
  280.  
  281.             if (!abort) {
  282.             for (i=1 ; i<num ; i++) {
  283.                 if (!stack->addCard(list[i])) {
  284.                 Punt("Bug in CardHandleEvent!");
  285.                 }
  286.             }
  287.             AutoMoves();
  288.             UndoBoundary();
  289.             }
  290.             break;
  291.         }
  292.         }
  293.     }
  294.     if (abort) {
  295.         for (i=0 ; i<num ; i++) list[i]->setLoc(origx[i], origy[i]);
  296.     }
  297.     }
  298.     return True;
  299. }
  300.     
  301.     
  302.  
  303.  
  304. void CardInit() {
  305.     unsigned long red = GetColor("red", "grey50", BlackPixel(dpy, screen));
  306.     unsigned long white = GetColor("white", "white", WhitePixel(dpy, screen));
  307.     unsigned long black = GetColor("black", "black", BlackPixel(dpy, screen));
  308.  
  309.     for (int s=0 ; s<NUMSUITS ; s++) {
  310.     for (int v=0 ; v<NUMVALUES ; v++) {
  311.         cards[s][v] = new CardRec(s, v, (s >= 2) ? black : red, white,
  312.                       card_bits[s * 13 + v]);
  313.     }
  314.     }
  315.  
  316.     highlightgc = XCreateGC(dpy, toplevel, 0, NULL);
  317.     XSetForeground(dpy, highlightgc,
  318.            GetColor("blue", "grey30", BlackPixel(dpy, screen)));
  319. }
  320.